﻿Imports org.codegen.win.controls
Imports org.model.lib.db

''' <summary>
''' This is the UI type of the criterion
''' </summary>
''' <remarks></remarks>
Public Enum enumReportCriterionUIType

    ''' <summary>
    ''' Text box
    ''' </summary>
    ''' <remarks></remarks>
    [TEXT] = 0
    ''' <summary>
    ''' Combo box
    ''' </summary>
    ''' <remarks></remarks>
    [COMBO] = 1

    DATE_TEXTBOX = 2

    DATE_TIME_TEXTBOX = 3

    TIME_TEXTBOX = 4

    INTEGER_TEXTBOX = 5

    DECIMAL_TEXTBOX = 6

End Enum
''' <summary>
''' Describes a report criterion (meta data)
''' </summary>
''' <remarks></remarks>
Public Class CriterionMetadata
    Implements ICriterionMetadata

    Private _width As Integer = 300

    Public Property Name As String Implements ICriterionMetadata.Name
    Public Property SqlFieldName As String Implements ICriterionMetadata.SqlFieldName
    Public Property controlUIType As enumReportCriterionUIType = enumReportCriterionUIType.TEXT Implements ICriterionMetadata.controlUIType

    Public Property isRange As Boolean = False Implements ICriterionMetadata.isRange

    Public Property isMandatory As Boolean = False Implements ICriterionMetadata.isMandatory
    Public Property isMandatory2 As Boolean Implements ICriterionMetadata.isMandatory2

    Public Property selectedvalue As Object Implements ICriterionMetadata.selectedvalue
    Public Property selectedvalue2 As Object Implements ICriterionMetadata.selectedvalue2

    Public Property selectedDisplayValue As String Implements ICriterionMetadata.selectedDisplayValue
    Public Property selectedDisplayValue2 As String Implements ICriterionMetadata.selectedDisplayValue2

    Private _defaultValue As String
    Public Property defaultValue As String Implements ICriterionMetadata.defaultValue

        Get
            Return getDefaultValueParsed(Me._defaultValue)
        End Get

        Set(ByVal value As String)
            _defaultValue = value
        End Set
    End Property

    Private _defaultValue2 As String
    Public Property defaultValue2 As String Implements ICriterionMetadata.defaultValue2
        Get
            Return getDefaultValueParsed(Me._defaultValue2)
        End Get

        Set(ByVal value As String)
            _defaultValue2 = value
        End Set

    End Property
    Public Property labelText As String Implements ICriterionMetadata.labelText
    Public Property labelText2 As String Implements ICriterionMetadata.labelText2

    Public Property isReadOnly As Boolean Implements ICriterionMetadata.isReadOnly
    Public Property isReadOnly2 As Boolean Implements ICriterionMetadata.isReadOnly2

    'if combo box, the SQL statement to execute and fill list items
    'the sql statement must return 2 fields, ID and Description
    Public Property comboBoxDataSource As String Implements ICriterionMetadata.comboBoxDataSource

    Private Const TO_CONTROL_SUFFIX As String = "_To"

    ''' <summary>
    ''' This is a public proeprty to allow for a system wide, default criterion GUI handler.
    ''' </summary>
    ''' <remarks></remarks>
    Public Shared defaultCriterionUIHandler As ICriterionUIHandler

    ''' <summary>
    ''' The help text of this control
    ''' </summary>
    Public Property helpText As String Implements ICriterionMetadata.helpText

    ''' <summary>
    ''' Hidden fields are on the page but not shown to the user
    ''' </summary>
    ''' <remarks>
    ''' Hidden fields are used when we want to pass a paremeter as a fixed value, but this value
    ''' changes at runtime.  For example, the current username, or current print date
    ''' </remarks>
    Public Property isHidden As Boolean Implements ICriterionMetadata.isHidden

    ''' <summary>
    ''' Transient fields are not used to build sql and pass the value as a filter
    ''' They are there as helper fields
    ''' </summary>
    Public Property isTransient As Boolean Implements ICriterionMetadata.isTransient

    Private _criterionHandler As ICriterionUIHandler
    Private _criterionWhereClauseBuilder As ICriterionProcessor
    Private _SqlOperator As String
    Private _SqlExpression As String

    ''' <summary>
    ''' Returns the class that builds the sql clause of this criterion.
    ''' If this class is not set, the <see cref="DefaultCriterionProcessor">DefaultCriterionWhereClauseBuilder</see>
    ''' is returned
    ''' </summary>
    Public Property criterionWhereClauseBuilder As ICriterionProcessor _
         Implements ICriterionMetadata.criterionBuilder
        Get
            If _criterionWhereClauseBuilder Is Nothing Then
                _criterionWhereClauseBuilder = New DefaultCriterionProcessor
            End If
            Return _criterionWhereClauseBuilder
        End Get
        Set(ByVal value As ICriterionProcessor)
            Me._criterionWhereClauseBuilder = value
        End Set
    End Property

    Public Property SqlExpression As String Implements ICriterionMetadata.SqlExpression
        Get
            If String.IsNullOrEmpty(Me._SqlExpression) Then
                If isRange Then
                    Me._SqlExpression = Me.SqlFieldName & " BETWEEN {0} AND {1} "
                Else
                    Me._SqlExpression = Me.SqlFieldName & Me.SqlOperator & "{0}"
                End If

            End If
            Return Me._SqlExpression
        End Get
        Set(ByVal value As String)
            Me._SqlExpression = value
        End Set
    End Property


    Public ReadOnly Property Name2 As String Implements ICriterionMetadata.Name2
        Get
            Return Me.Name & TO_CONTROL_SUFFIX
        End Get
    End Property


    Public Property criterionHandler() As ICriterionUIHandler Implements ICriterionMetadata.criterionHandler
        Get
            If _criterionHandler Is Nothing AndAlso _
                        defaultCriterionUIHandler IsNot Nothing Then

                _criterionHandler = defaultCriterionUIHandler
            End If


            Return _criterionHandler
        End Get
        Set(ByVal value As ICriterionUIHandler)
            _criterionHandler = value
        End Set
    End Property

    Public Function getUIControl() As Control Implements ICriterionMetadata.getUIControl

        Dim ret As Control = Nothing

        Select Case Me.controlUIType
            Case enumReportCriterionUIType.TEXT
                ret = New CGTextBox

            Case enumReportCriterionUIType.COMBO
                Dim cbo As New CGComboBox
                If String.IsNullOrEmpty(Me.comboBoxDataSource) = False Then
                    cbo.DataSource = DBUtils.Current.getDataTable(Me.comboBoxDataSource).DefaultView
                    cbo.DisplayMember = "Description"
                    cbo.ValueMember = "Id"

                End If

                ret = cbo

            Case enumReportCriterionUIType.DATE_TEXTBOX
                ret = New CGDateTextBox

            Case enumReportCriterionUIType.DATE_TIME_TEXTBOX
                ret = New CGTimeBox

            Case enumReportCriterionUIType.TIME_TEXTBOX
                ret = New CGTimeBox

            Case enumReportCriterionUIType.DECIMAL_TEXTBOX
                ret = New CGDecimalTextBox

            Case enumReportCriterionUIType.INTEGER_TEXTBOX
                ret = New CGIntTextBox

            Case Else
                Throw New ApplicationException("Undlandled enumReportCriterionUIType:" & Me.controlUIType)

        End Select

        If Me.criterionHandler IsNot Nothing Then
            Me.criterionHandler.renderControlHandler(ret, Me)
        End If

        Return ret

    End Function

    Public Function getUIValue(ByVal c As Control) As Object Implements ICriterionMetadata.getValue

        Dim retval As Object

        Select Case Me.controlUIType
            Case enumReportCriterionUIType.TEXT
                retval = c.Text

            Case enumReportCriterionUIType.COMBO
                Dim cbo As CGComboBox = CType(c, CGComboBox)
                retval = cbo.Value

            Case enumReportCriterionUIType.DATE_TEXTBOX
                Dim cbo As CGDateTextBox = CType(c, CGDateTextBox)
                retval = cbo.DateValue

            Case enumReportCriterionUIType.DATE_TIME_TEXTBOX
                Dim cbo As CGDateTextBox = CType(c, CGDateTextBox)
                retval = cbo.DateValue

            Case enumReportCriterionUIType.DECIMAL_TEXTBOX

                Dim cbo As CGDecimalTextBox = CType(c, CGDecimalTextBox)
                retval = cbo.decimalValue

            Case enumReportCriterionUIType.INTEGER_TEXTBOX
                '                        enumReportCriterionUIType.YEAR, _
                '                        enumReportCriterionUIType.MONTH


                Dim cbo As CGIntTextBox = CType(c, CGIntTextBox)
                retval = cbo.integerValue

            Case Else
                Throw New ApplicationException("Undlandled enumReportCriterionUIType:" & Me.controlUIType)

        End Select

        If Me.criterionHandler IsNot Nothing Then
            Me.criterionHandler.controlValueHandler(retval, c, Me)
        End If

        Return retval

    End Function

    Public Function getUIDisplayValue(ByVal c As Control) As String _
                Implements ICriterionMetadata.getDisplayValue

        Dim retval As String

        Select Case Me.controlUIType
            Case enumReportCriterionUIType.TEXT
                retval = c.Text

            Case enumReportCriterionUIType.COMBO
                Dim cbo As CGComboBox = CType(c, CGComboBox)
                retval = cbo.Text

            Case enumReportCriterionUIType.DATE_TEXTBOX
                Dim cbo As CGDateTextBox = CType(c, CGDateTextBox)
                If cbo.DateValue Is Nothing Then
                    retval = String.Empty
                Else
                    retval = cbo.DateValue.GetValueOrDefault.ToShortDateString()
                End If


            Case enumReportCriterionUIType.DATE_TIME_TEXTBOX
                Dim cbo As CGDateTextBox = CType(c, CGDateTextBox)
                If cbo.DateValue Is Nothing Then
                    retval = String.Empty
                Else
                    retval = cbo.DateValue.GetValueOrDefault.ToShortDateString() & _
                         " " & cbo.DateValue.GetValueOrDefault.ToShortTimeString()
                End If

            Case enumReportCriterionUIType.DECIMAL_TEXTBOX

                Dim cbo As CGDecimalTextBox = CType(c, CGDecimalTextBox)
                If cbo.decimalValue Is Nothing Then
                    retval = String.Empty
                Else
                    retval = cbo.decimalValue.GetValueOrDefault.ToString("g")
                End If

            Case enumReportCriterionUIType.INTEGER_TEXTBOX
                '                        enumReportCriterionUIType.YEAR, _
                '                        enumReportCriterionUIType.MONTH


                Dim cbo As CGIntTextBox = CType(c, CGIntTextBox)
                retval = cbo.integerValue.ToString

            Case Else
                Throw New ApplicationException("Undlandled enumReportCriterionUIType:" & Me.controlUIType)

        End Select

        If Me.criterionHandler IsNot Nothing Then
            Me.criterionHandler.controlDisplayValueHandler(retval, c, Me)
        End If

        Return retval

    End Function

    Shared Function getDefaultValueParsed(ByVal defdefault As String) As String

        If defdefault = "now" Then
            Return Now.ToString("G")

        ElseIf defdefault = "today" Then
            Return Now.ToString("d")

        ElseIf defdefault = "current_year" Then
            Return CStr(Year(Now))
        Else
            Return defdefault
        End If

    End Function

    Public Property width As Integer Implements ICriterionMetadata.width
        Get
            If Me._width <= 0 Then
                Return 200
            Else
                Return Me._width
            End If
        End Get
        Set(ByVal value As Integer)
            Me._width = value
        End Set
    End Property


    Public Property SqlOperator As String Implements ICriterionMetadata.SqlOperator
        Get
            If Me.isRange Then
                Return " BETWEEN "
            Else
                If String.IsNullOrEmpty(Me._SqlOperator) Then
                    Me._SqlOperator = "="
                End If
                Return Me._SqlOperator
            End If
        End Get
        Set(ByVal value As String)
            If UCase(Trim(value)) = "LIKE" Then
                value = " LIKE "
            End If
            Me._SqlOperator = value
        End Set
    End Property

    Public Function hasValue() As Boolean Implements ICriterionMetadata.hasValue

        Return Me.selectedvalue IsNot Nothing AndAlso (Not String.IsNullOrEmpty(CStr(Me.selectedvalue)))

    End Function

    Public Function hasValue2() As Boolean Implements ICriterionMetadata.hasValue2

        Return Me.selectedvalue2 IsNot Nothing AndAlso (Not String.IsNullOrEmpty(CStr(Me.selectedvalue2)))

    End Function

       
End Class
